﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace AlphaBeatSoundEngine
{
    public class TimedTone
    {

        private Tone _tone;
        private ToneMeasureLength _length;
        private MusicStyle _style;
        private bool _timeMarked;

        public Tone Tone { get { return _tone; } }
        public ToneMeasureLength ToneLenght { get { return _length; } }
        public MusicStyle Style { get { return _style; } }
        public String SoundLocation { get { return _style.SoundForTone(this); } }
        public bool TimeMarked { get { return _timeMarked; } }

        public TimedTone(Tone tone, ToneMeasureLength length, MusicStyle style, bool timeMarked = false)
        {
            _tone = tone;
            _length = length;
            _style = style;
            _timeMarked = timeMarked;
        }

        public TimedTone(String tone, String length, MusicStyle style, bool timeMarked = false)
        {
            _tone = ToneFromString(tone);
            _length = LengthFromString(length);
            _style = style;
            _timeMarked = timeMarked;
        }

        private Tone ToneFromString(string s)
        {
            switch (s)
            {
                case "A": return Tone.A;
                case "ASharp": return Tone.ASharp;
                case "B": return Tone.B;
                //case "BSharp": return Tone.C; //TODO delete once xml file has been modified
                case "C": return Tone.C;
                case "CSharp": return Tone.CSharp;
                case "D": return Tone.D;
                case "DSharp": return Tone.DSharp;
                case "E": return Tone.E;
                case "F": return Tone.F;
                case "FSharp": return Tone.FSharp;
                case "G": return Tone.G;
                case "GSharp": return Tone.GSharp;

                default: return Tone.A;
            }
        }

        private ToneMeasureLength LengthFromString(string length)
        {
            switch (length)
            {
                case "1": return ToneMeasureLength.Time;
                case "1/2": return ToneMeasureLength.HalfTime;
                case "2": return ToneMeasureLength.DoubleTime;
                case "4": return ToneMeasureLength.QuadrupleTime;
                case "8": return ToneMeasureLength.EightTime;
                case "1/4": return ToneMeasureLength.QuarterTime;

                default: return ToneMeasureLength.Time;
            }
        }

        public override string ToString()
        {
            string acc = (_timeMarked) ? "!" : "";
            return "[" + _tone.ToString() + " " + _length.ToFractionnedString() + acc + "]";
        }

        public override bool Equals(System.Object obj)
        {
            // If parameter is null return false.
            if (obj == null)
            {
                return false;
            }

            // If parameter cannot be cast to Point return false.
            TimedTone t = obj as TimedTone;
            if ((System.Object)t == null)
            {
                return false;
            }

            // Return true if the fields match:
            return (_length == t._length) && (_tone == t._tone) && (_style == t._style);
        }

        public bool Equals(TimedTone t)
        {
            // If parameter is null return false:
            if ((object)t == null)
            {
                return false;
            }

            // Return true if the fields match:
            return (_length == t._length) && (_tone == t._tone) && (_style == t._style);
        }

        public override int GetHashCode()
        {
            return (int)_length ^ (int)_tone ^ _style.GetHashCode();
        }
    }

    
}
